﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SweeperPrototype.Business.Fields;
using SweeperPrototype.Objects;
using SweeperPrototype.Plumbing;

namespace SweeperPrototype.Business.Plumbing
{
    public class LinkEffectiveExposures : ListLink<PositionSubscription, EffectiveExposure>
    {
        private readonly EffectiveExposureProvider m_Provider;
        private readonly List<NotifyList<EffectiveExposure>> m_ListCache;
        
        public LinkEffectiveExposures(
            INotifyList<PositionSubscription> source_list,
            out NotifyList<EffectiveExposure> result_list,
            EffectiveExposureProvider provider ):
            base( source_list, out result_list )
        {
            m_ListCache = new List<NotifyList<EffectiveExposure>>();
            m_Provider = provider;
            SourceList.Addition += HandlePositionAdded;
            SourceList.Removal += HandlePositionRemoved;
        }

        private void HandlePositionRemoved(PositionSubscription removal, int index)
        {
            NotifyList<EffectiveExposure> list;
            if (m_Provider.TryGet(new PositionSubscription.UniqueKey(removal), out list))
            {
                m_ListCache.Remove(list);

                list.Addition -= HandleEffectiveExposureAddition;
                list.Removal -= HandleEffectiveExposureRemoval;
                int current_count = list.Count;
                for( int i=0 ; i < current_count ; i++ )
                {
                    HandleEffectiveExposureRemoval(list[i],-1);    
                }
            }
        }

        private void HandlePositionAdded(PositionSubscription addition, int index)
        {
            NotifyList<EffectiveExposure> list;
            if( m_Provider.TryGet( new PositionSubscription.UniqueKey(addition), out list ) )
            {
                m_ListCache.Add( list );
                list.Addition += HandleEffectiveExposureAddition;
                list.Removal += HandleEffectiveExposureRemoval;

                foreach( EffectiveExposure effex in list )
                {
                    HandleEffectiveExposureAddition( effex, index );
                }
            }
            else
            {
                throw new Exception("Bad assumption");
            }
        }

        private void HandleEffectiveExposureRemoval(EffectiveExposure removal, int index)
        {
            // NOTE: we can't rely on these indexes...
            m_ResultList.Remove(removal);
        }

        private void HandleEffectiveExposureAddition(EffectiveExposure addition, int index)
        {
            // NOTE: we can't rely on these indexes...
            m_ResultList.Add(addition);
        }
    }
}
